home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Utilities / PalmLink / src / PL_PADP.c < prev    next >
C/C++ Source or Header  |  2000-05-05  |  8KB  |  300 lines

  1. /**
  2.  * PalmLink -- Connect 3Com Palm with Amiga
  3.  *
  4.  * PADP (Packet Assembly Disassembly Protocol)
  5.  *
  6.  * (C) 1998-2000 Richard Körber <rkoerber@gmx.de>
  7.  *
  8.  *------------------------------------------------------------------
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  *
  24.  * You must not use this source code to gain profit of any kind!
  25.  */
  26.  
  27. #include "palmlink_glob.h"
  28.  
  29. /*------------------------------------------------------**
  30. ** Name:        PL_PADPWrite                      public
  31. **
  32. ** Funktion:    Verschickt ein PADP-Paket
  33. **
  34. ** Parameter:   socket    Socket für die Übertragung
  35. **              buffer    zu übertragener Puffer
  36. **              length    Länge des Puffers
  37. **              type      Zu übertragener Typ
  38. ** Ergebnis:    length    Geschriebene Bytes, oder
  39. **                        -1: Fehler
  40. //>
  41. ** Bemerkungen:
  42. **
  43. ** Revision:    31. Mai 1998, 21:14:30
  44. */
  45. __saveds __asm LONG PL_PADPWrite
  46. (
  47.   register __a0 APTR socket,
  48.   register __a1 APTR buffer,
  49.   register __d0 LONG length,
  50.   register __d1 UWORD type
  51. )
  52. {
  53.   struct PL_Socket *sock = (struct PL_Socket *)socket;
  54.   struct PL_SLP_Header slp;       // SLP header
  55.   struct PL_SLP_Header recslp;    // SLP header to be received
  56.   struct PL_PADP_Header padp;     // PADP header
  57.   UBYTE flags = PLPADPF_FIRST;
  58.   LONG  remain = length;          // bytes remaining to be sent
  59.   LONG  offset = 0;
  60.   LONG  plen;
  61.  
  62.   sock->lastError = PLERR_OKAY;
  63.  
  64.   /* Create transaction ID */
  65.   if(type==PLPADP_WAKE)
  66.   {
  67.     sock->transactionID = 0xFF;
  68.   }
  69.   else if(type!=PLPADP_ACK && !sock->initiator)
  70.   {
  71.     sock->transactionID++;
  72.     if((sock->transactionID==0x00) || (sock->transactionID==0xFF)) // wrap around in time
  73.       sock->transactionID=0x01;
  74.   }
  75.   else if(sock->transactionID==0x00)
  76.   {
  77.     sock->transactionID = 0x10;   // or another value
  78.   }
  79.  
  80.   /* create SLP header */
  81.   slp.destSocket = PLSLPSOCK_DLP;
  82.   slp.srcSocket  = PLSLPSOCK_DLP;
  83.   slp.pckType    = PLSLPTYPE_PADP;
  84.   slp.transID    = sock->transactionID;
  85.  
  86.   /* transfer data */
  87.   do
  88.   {
  89.     plen = min(remain,1024);
  90.  
  91.     /* create PADP header */
  92.     padp.type      = type & 0xFF;
  93.     padp.flags     = (remain==plen ? flags|PLPADPF_LAST : flags);
  94.     padp.size      = (flags!=0 ? length : offset);
  95.  
  96. #ifdef PADPDEBUG
  97.   Printf("PADP A->P: type=%ld flags=0x%02lx size=%ld tID=0x%02lx\n",padp.type,padp.flags,padp.size,slp.transID);
  98. #endif
  99.  
  100.  
  101.     /* send data */
  102.     if(PL_SLPWrite(socket,((UBYTE *)buffer)+offset,plen,&slp,&padp) == -1)
  103.     {
  104.       offset = -1;               // error
  105.       break;
  106.     }
  107.  
  108.     /* eventually wait for ACK */
  109.     if(type != PLPADP_TICKLE)   // tickles are not acknowledged
  110.     {
  111.       for(;;)
  112.       {
  113.         /*TODO: this is ugly, because it is not error tolerant */
  114.  
  115.         if(!PL_SLPRead(socket,global.slptrash,1024,&recslp,&padp) == -1)
  116.         {
  117.           offset = -1;             // error
  118.           goto error;
  119.         }
  120.  
  121.         if(padp.flags & PLPADPF_MEMERROR)
  122.         {
  123.           if(slp.transID == recslp.transID)
  124.           {
  125.             sock->lastError = PLERR_REMOTENOMEM;
  126.             offset = -1;
  127.             goto error;
  128.           }
  129.           else continue;          // bad packet at wrong time
  130.         }
  131.  
  132.         if(padp.type == PLPADP_TICKLE)
  133.           continue;               // tickles are ignored
  134.  
  135.         if(   (padp.type != PLPADP_ACK)
  136.            || (slp.transID != recslp.transID))
  137.         {
  138.           sock->lastError = PLERR_BADPACKET;
  139.           offset = -1;
  140. #ifdef DEBUGOUT
  141.   Printf("DEBUG: File %s Line %ld: Bad Packet\n",__FILE__,__LINE__);
  142.   Printf("  padp.type = %ld\n  slp.transID = %ld\n  recslp.transID = %ld\n",padp.type,slp.transID,recslp.transID);
  143.   Printf("  slptrash = %08lx %08lx %08lx %08lx\n",((ULONG *)global.slptrash)[0],((ULONG *)global.slptrash)[1],((ULONG *)global.slptrash)[2],((ULONG *)global.slptrash)[3]);
  144. #endif
  145.           goto error;             // Our packet is not acknowledged?!
  146.         }
  147.  
  148. #ifdef PADPDEBUG
  149.   Printf("PADP A->P: [received good ACK]\n");
  150. #endif
  151.  
  152.         break;                    // Everything is fine: next packet
  153.       }
  154.     }
  155.  
  156.     offset += plen;
  157.     remain -= plen;
  158.     flags  = 0;                   // Not the FIRST any more
  159.   }
  160.   while(remain>0);
  161.  
  162. error:
  163.   if(type!=PLPADP_ACK && sock->initiator)
  164.   {
  165.     sock->transactionID++;
  166.     if(sock->transactionID==0xFF)
  167.       sock->transactionID=0x01;
  168.   }
  169.  
  170.   return(offset);
  171. }
  172. //<
  173.  
  174. /*------------------------------------------------------**
  175. ** Name:        PL_PADPRead                       public
  176. **
  177. ** Funktion:    Holt ein PADP-Paket
  178. **
  179. ** Parameter:   socket    Socket für die Übertragung
  180. **              buffer    Empfangspuffer
  181. **              length    Pufferlänge
  182. ** Ergebnis:    length    Länge des empfangenen Puffers,
  183. **                        -1: Fehler
  184. //>
  185. ** Bemerkungen:
  186. **
  187. ** Revision:     1. Juni 1998, 17:33:41
  188. */
  189. __saveds __asm LONG PL_PADPRead
  190. (
  191.   register __a0 APTR socket,
  192.   register __a1 APTR buffer,
  193.   register __d0 LONG length
  194. )
  195. {
  196.   struct PL_Socket *sock = (struct PL_Socket *)socket;
  197.  
  198.   struct PL_PADP_Header padp;
  199.   struct PL_SLP_Header  slp;
  200.   struct PL_PADP_Header ackpadp;
  201.   struct PL_SLP_Header  ackslp =
  202.   {
  203.     0,0,0,
  204.     PLSLPSOCK_DLP,
  205.     PLSLPSOCK_DLP,
  206.     PLSLPTYPE_PADP,
  207.     0,
  208.     0,
  209.     0
  210.   };
  211.  
  212.   LONG   offset = 0;
  213.   LONG   gotoffset;
  214.   LONG   remain = length;
  215.   LONG   read;
  216.  
  217.   sock->lastError = PLERR_OKAY;
  218.  
  219.   /* Create transaction ID */
  220.   if(sock->initiator)
  221.   {
  222.     sock->transactionID++;
  223.     if(sock->transactionID==0xFF)
  224.       sock->transactionID=0x01;
  225.   }
  226.  
  227.   /* Receive data */
  228.   do
  229.   {
  230.     /* read packet */
  231.     read = PL_SLPRead(socket,((UBYTE *)buffer)+offset,remain,&slp,&padp);
  232.     if(read == -1)                        // Error occured
  233.     {
  234.       offset = -1;
  235.       break;
  236.     }
  237.  
  238.     /* check for plausibility */
  239.     if(padp.type == PLPADP_TICKLE)        // Don't care about tickles
  240.     {
  241.       continue;
  242.     }
  243.  
  244.     if(padp.type == PLPADP_ACK)           // Acknowledge
  245.     {
  246.       // No acknowledges should occur. Anyhow, if we get an acknowledge,
  247.       // we will just ignore it.
  248.       continue;
  249.     }
  250.  
  251.     gotoffset = (padp.flags & PLPADPF_FIRST ? 0 : padp.size);
  252.  
  253.     if(   (padp.type != PLPADP_DATA)      // Bad packet?
  254.        || (slp.transID != sock->transactionID)
  255.        || (offset==0 && !(padp.flags&PLPADPF_FIRST))
  256.        || (gotoffset != offset)
  257.       )
  258.     {
  259.       sock->lastError = PLERR_BADPACKET;
  260.       offset = -1;
  261. #ifdef DEBUGOUT
  262.   Printf("DEBUG: File %s Line %ld: Bad Packet\n",__FILE__,__LINE__);
  263. #endif
  264.       break;
  265.     }
  266.  
  267. #ifdef PADPDEBUG
  268.   Printf("PADP A<-P: type=%ld flags=0x%02lx size=%ld tID=0x%02lx\n",padp.type,padp.flags,padp.size,slp.transID);
  269. #endif
  270.  
  271.     /* Send ACK */
  272.     ackpadp.type   = PLPADP_ACK;
  273.     ackpadp.flags  = padp.flags;
  274.     ackpadp.size   = padp.size;
  275.     ackslp.transID = sock->transactionID;
  276.     if(-1 == PL_SLPWrite(socket,&ackpadp,sizeof(struct PL_PADP_Header),&ackslp,NULL))
  277.     {
  278.       offset = -1;
  279.       break;
  280.     }
  281.  
  282. #ifdef PADPDEBUG
  283.   Printf("PADP A<-P: [sent ACK]\n");
  284. #endif
  285.  
  286.     /* Next Packet */
  287.     offset += read;
  288.     remain -= read;
  289.  
  290.     if(padp.flags&PLPADPF_LAST) break;
  291.   }
  292.   while(remain>0);
  293.  
  294.   return(offset);                         // Packets received
  295. }
  296. //<
  297.  
  298.  
  299. /********************************************************************/
  300.